package com.tanovo.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tanovo.bo.EsBatchAddReq;
import com.tanovo.bo.IndexBo;
import com.tanovo.bo.UserCore;
import com.tanovo.config.UserInfoContext;
import com.tanovo.service.EsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
@Slf4j
public class EsServiceImpl implements EsService {
    @Override
    public RestHighLevelClient getHighClient() {
        //  getHost() 为获取链接集群的地址
        HttpHost[] host = new HttpHost[]{HttpHost.create("http://10.10.40.15:9200")};
        RestClientBuilder builder = RestClient.builder(host);
        // 设置ES 链接密码
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
        // 创建高级搜索链接，请注意改链接使用完成后必须关闭，否则使用一段时间之后将会抛出异常
        RestHighLevelClient restClient = new RestHighLevelClient(builder);
        return restClient;
    }

    public BulkResponse upsetIndex(EsBatchAddReq esBatchAddReq) {
        BulkResponse bulk = null;
        try {  // 获取链接
            String indexStr = this.buildIndexName(esBatchAddReq.getIndexName());
            RestHighLevelClient highClient = getHighClient();
            BulkRequest request = new BulkRequest();
            // 设置索引名称，索引名称由系统编码和业务编码组成。若业务比较简单，也可以仅设置为一个字段。此处是为了方便多系统多业务使用
//            request.routing(requestParam.getEsCode());
            for (Object o : esBatchAddReq.getBeanList()) {
                JSONObject jsonObject = (JSONObject) JSON.toJSON(o);
                String id = jsonObject.getString("id");
                // 将数据转换为String类型，批量插入时设置为JSON格式
                String data = JSONObject.toJSONString(o);
                // 实体类必须包含ES自定义主键，搜索引擎ES将根据自定义ID进行重复新验证。
                request.add(new IndexRequest(indexStr).id(id).source(data, XContentType.JSON));
            }
            // 批量新增数据
            bulk = highClient.bulk(request, RequestOptions.DEFAULT);
            // 关闭链接
            highClient.close();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("============es服务出现网络问题===============");
            throw new RuntimeException("es服务出现网络问题");
        }
        return bulk;
    }

    @Override
    public CreateIndexResponse createIndex(String indexName) {
        String indexStr = this.buildIndexName(indexName);
        CreateIndexResponse response = null;
        try {
            RestHighLevelClient highClient = getHighClient();
            CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexStr);
            log.info("当前用户：{}======创建索引：{}", JSONObject.toJSONString(UserInfoContext.getUser()), indexStr);
            response = highClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("============es服务出现网络问题===============",e);
            throw new RuntimeException("es服务出现网络问题");

        }
        return response;
    }

    @Override
    public Boolean existIndex(String indexName) {
        String indexStr = this.buildIndexName(indexName);
        GetIndexRequest getIndexRequest = new GetIndexRequest(indexStr);
        RestHighLevelClient highClient = getHighClient();
        boolean exists = false;
        try {
            exists = highClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("============es服务出现网络问题===============",e);
            throw new RuntimeException("es服务出现网络问题");
        }
        return exists;
    }

    @Override
    public AcknowledgedResponse deleteIndex(String indexName) {
        String indexStr = this.buildIndexName(indexName);
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexStr);
        RestHighLevelClient highClient = getHighClient();
        AcknowledgedResponse acknowledgedResponse = null;
        try {
            acknowledgedResponse = highClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("============es服务出现网络问题===============",e);
            throw new RuntimeException("es服务出现网络问题");
        }
        return acknowledgedResponse;
    }

    @Override
    public Boolean existDoc(IndexBo indexBo) {
        String indexName = this.buildIndexName(indexBo.getIndexName());


        return null;
    }

    private String buildIndexName(String indexName) {
        UserCore user = UserInfoContext.getUser();
        String indexStr = null;
        if (user != null) {
            indexStr = user.getClientId() + "_" + indexName;
        } else {
            indexStr = "tanovo_df_" + indexName;
        }
        return indexStr;
    }

    @Override
    public GetResponse getDocInfo(IndexBo indexBo) {
        String indexName = this.buildIndexName(indexBo.getIndexName());
        GetRequest getRequest = new GetRequest(indexName, indexBo.getId());
        RestHighLevelClient highClient = getHighClient();
        GetResponse getResponse = null;
        try {
            getResponse = highClient.get(getRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("============es服务出现网络问题===============",e);
            throw new RuntimeException("es服务出现网络问题");
        }
        return getResponse;
    }

    @Override
    public UpdateResponse updateDocInfo(IndexBo indexBo) {
        return null;
    }

    @Override
    public DeleteResponse deleteDocInfo(IndexBo indexBo) {
        return null;
    }


}
